/**************************************************************************************************
**                                                                                               **
**  文件名称:  osl_tmr_man.c                                                                     **
**  版权所有:  CopyRight @ Xiamen Yaxon NetWork CO.LTD. 2017                                     **
**  文件描述:  系统定时器调度和管理                                                              **
**  ===========================================================================================  **
**  创建信息:  | 2017-6-29 | LEON | 创建本模块                                                   **
**  ===========================================================================================  **
**  修改信息:  单击此处添加....                                                                  **
**************************************************************************************************/
#include "osl_include.h"
#include "osl_tmr_man.h"

/*************************************************************************************************/
/*                           模块宏定义                                                          */
/*************************************************************************************************/
#define MAX_SYSTIMER         20

/*************************************************************************************************/
/*                           模块结构体                                                          */
/*************************************************************************************************/
typedef struct {
    INT8U      ready;                                                          /* 是否就绪 */
    INT32U     ttime;                                                          /* 总定时时间 */
    INT32U     ltime;                                                          /* 剩余时间 */
    void     (*tproc)(void);                                                   /* 回调函数 */
    void     (*bproc)(void);                                                   /* 备份函数 */
} SYSTMR_T;

/*************************************************************************************************/
/*                           模块静态变量                                                        */
/*************************************************************************************************/
static SYSTMR_T     s_systmrctrl[MAX_SYSTIMER];
static INT32U       s_systicks, s_preticks;                                    /* 当前tick的值，前次的值 */

/**************************************************************************************************
**  函数名称:  SysTickHandler
**  功能描述:  定时器中断处理函数
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void SysTickHandler(void)
{
	 s_systicks++;
}

/**************************************************************************************************
**  函数名称:  SysTickStartup
**  功能描述:  启动systick
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**  注意事项:  除以1000表示基准为1ms，除以100表示基准为10ms
**************************************************************************************************/
void SysTickStartup(void)
{
    while (SysTick_Config(SystemCoreClock / 1000));
    
    BSP_ConfigIRQPriority(SysTick_IRQn, IRQ_PRIOTITY_SYSTICK);
    BSP_InstallIRQHandler(SysTick_IRQn, (IRQ_SERVICE_FUNC)SysTickHandler);
}

/**************************************************************************************************
**  函数名称:  OSL_TmrManInit
**  功能描述:  定时器模块初始化函数
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_TmrManInit(void)
{
    INT8U i;
    
    for (i = 0; i < MAX_SYSTIMER; i++) {
        s_systmrctrl[i].ready = false;
        s_systmrctrl[i].tproc = 0;
        s_systmrctrl[i].bproc = 0;
    }
    
    s_preticks = 0;
    s_systicks = 0;
    
    SysTickStartup();
}

/**************************************************************************************************
**  函数名称:  OSL_CreateTimer
**  功能描述:  创建定时器
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
INT8U OSL_CreateTimer(void (*tproc)(void))
{
    INT8U id;
    
    SYS_ASSERT((tproc != 0), 0xFF);
    
    for (id = 0; id < MAX_SYSTIMER; id++) {                                    /* 查找一个空定时器 */
        if (s_systmrctrl[id].tproc == 0) {
            break;
        }
    }
    
    SYS_ASSERT((id < MAX_SYSTIMER), 0xFF);                                     /* 找不到一个空定时器 */
    
    s_systmrctrl[id].ready = FALSE;
    s_systmrctrl[id].ttime = 0x00;
    s_systmrctrl[id].ltime = 0x00;
    s_systmrctrl[id].tproc = tproc;
    s_systmrctrl[id].bproc = tproc;
    
    return id;
}

/**************************************************************************************************
**  函数名称:  OSL_RemoveTimer
**  功能描述:  删除一个已创建的定时器
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_RemoveTimer(INT8U id)
{
    SYS_ASSERT((id < MAX_SYSTIMER), RETURN_VOID);
    
    s_systmrctrl[id].ttime = 0;
    s_systmrctrl[id].ltime = 0;
    s_systmrctrl[id].ready = FALSE;
    s_systmrctrl[id].tproc = 0;
    s_systmrctrl[id].bproc = 0;
}

/**************************************************************************************************
**  函数名称:  OSL_StartTimer
**  功能描述:  启动定时器
**  输入参数:  id: 定时器ID
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_StartTimer(INT8U id, INT32U attrib, INT32U time)
{
    SYS_ASSERT((id < MAX_SYSTIMER && s_systmrctrl[id].tproc != 0), RETURN_VOID);

    s_systmrctrl[id].ttime = (attrib * time);
    s_systmrctrl[id].ltime = s_systmrctrl[id].ttime;
    s_systmrctrl[id].ready = FALSE;
}

/**************************************************************************************************
**  函数名称:  OSL_StopTimer
**  功能描述:  停止定时器
**  输入参数:  id: 定时器ID
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void OSL_StopTimer(INT8U id)
{
    SYS_ASSERT((id < MAX_SYSTIMER), RETURN_VOID);

    s_systmrctrl[id].ttime = 0;
    s_systmrctrl[id].ltime = 0;
    s_systmrctrl[id].ready = FALSE;
}

/**************************************************************************************************
**  函数名称:  OSL_GetLeftTime
**  功能描述:  获取定时器还需要等待的超时时间
**  输入参数:  id: 定时器ID
**  输出参数:  无
**  返回参数:  剩余的运行时间, 单位: 一个tick
**************************************************************************************************/
INT32U OSL_GetLeftTime(INT8U id)
{
    SYS_ASSERT((id < MAX_SYSTIMER), 0);
    
    if (s_systmrctrl[id].tproc != 0 && s_systmrctrl[id].ttime > 0) {
        return (s_systmrctrl[id].ltime);
    } else {
        return 0;
    }
}

/**************************************************************************************************
**  函数名称:  OSL_TimerIsRun
**  功能描述:  判断定时器是否处于运行状态
**  输入参数:  id:  定时器ID
**  输出参数:  无
**  返回参数:  true: 运行状态, false: 停止状态
**************************************************************************************************/
INT8U OSL_TimerIsRun(INT8U id)
{
    SYS_ASSERT((id < MAX_SYSTIMER), RETURN_FALSE);
    
    if (s_systmrctrl[id].tproc != 0 && s_systmrctrl[id].ttime > 0) {
        return true;
    } else {
        return false;
    }
}

/**************************************************************************************************
**  函数名称:  SystemTimerEntry
**  功能描述:  系统定时器处理函数
**  输入参数:  无
**  输出参数:  无
**  返回参数:  无
**************************************************************************************************/
void SystemTimerEntry(void)
{
    INT32U i, time, curticks;
    
    if (s_preticks == s_systicks) {
        return;
    }
    
    curticks = s_systicks;
    
    if (curticks >= s_preticks) {
        time =  curticks - s_preticks;
    } else {
        time = (0xFFFFFFFF - s_preticks) + curticks;
    }
    
    s_preticks = curticks;                                                     /* 保存当前tick计数 */
    
    for (i = 0; i < MAX_SYSTIMER; i++) {
        
        if ((s_systmrctrl[i].tproc != 0) && (s_systmrctrl[i].ttime > 0)) {
            
            if (s_systmrctrl[i].ltime >= time) {
                s_systmrctrl[i].ltime -= time;
            } else {
                s_systmrctrl[i].ltime  = 0;
            }
            
            if (s_systmrctrl[i].ltime == 0) {
                                
                s_systmrctrl[i].ltime = s_systmrctrl[i].ttime;
                s_systmrctrl[i].ready = true;
                
                SYS_ASSERT(s_systmrctrl[i].tproc != NULL, RETURN_VOID);
                SYS_ASSERT(s_systmrctrl[i].tproc == s_systmrctrl[i].bproc, RETURN_VOID);
                
                s_systmrctrl[i].ready = false;
                s_systmrctrl[i].tproc();
            }
        }
    }
}

